﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ALDIOrganizer
{
    
    partial class ImprovedListView : System.Windows.Forms.ListView
    {
        /* for third-party code bit, see other part of this class
         * under the "Third-party code" folder */                
        internal List<Control> OnWhenSelected;
        internal delegate bool IsEditableDelegate();
        internal IsEditableDelegate IsEditable;

        protected override void OnSelectedIndexChanged(EventArgs e)
        {
            base.OnSelectedIndexChanged(e);
            var anything = (SelectedItems.Count != 0);

            foreach (var c in OnWhenSelected)
            {
                var enabled = anything;
                if (IsEditable != null)
                {
                    enabled &= IsEditable();
                }
                c.Enabled = enabled;
            }
        }

        internal void TriggerOnSelectedIndexChanged()
        {
            OnSelectedIndexChanged(null);
        }

        

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            AutoSizeColumns();
        }

        public ListViewItemTag SelectedTag
        {
            get
            {
                if (SelectedItems.Count == 0)
                {
                    return null;
                }
                var _tag = SelectedItems[0].Tag;                
                return _tag as ListViewItemTag;
            }
        }

        Dictionary<int, int> _columnsFillWeights;
        
        internal Dictionary<int, int> ColumnsFillWeights
        {
            get
            {
                return _columnsFillWeights;
            }
            set
            {
                _columnsFillWeights = value;
                AutoSizeColumns();
            }
        }

        public void SetColumnFillWeight(
            int pIndex,
            int pWeight)
        {
            if (pIndex >= Columns.Count)
            {
                return;
            }
            if (_columnsFillWeights.Keys.Contains(pIndex))
            {
                _columnsFillWeights[pIndex] = pWeight;
            }
            else
            {
                _columnsFillWeights.Add(pIndex, pWeight);
            }
        }

        List<int> _hiddenColumns;

        public void HideColumn(int pIndex)
        {
            if (pIndex >= Columns.Count |
                pIndex < 0)
            {
                return;
            }

            if(_hiddenColumns.Contains(pIndex))
            {
                return;
            }
                        
            _hiddenColumns.Add(pIndex);            
        }

        public void UnhideColumn(int pIndex)
        {
            if (pIndex >= Columns.Count |
                pIndex < 0)
            {
                return;
            }

            if(!_hiddenColumns.Contains(pIndex))
            {
                return;
            }

            _hiddenColumns.Remove(pIndex);
        }

        public void HideColumns(int[] pIndexes)
        {
            foreach (var i in pIndexes)
            {
                HideColumn(i);
            }
        }

        public void UnhideColumns(int[] pIndexes)
        {
            foreach (var i in pIndexes)
            {
                UnhideColumn(i);
            }
        }

        public void UnhideAllColumns()
        {
            _hiddenColumns.Clear();
        }

        public void AutoSizeColumns()
        {            
            #region summing all the Tag values up

            /* Tags may not sum up to 100. we need to count the "GetTotal" weight */
            int total = 0;

            int _limit = ColumnsFillWeights.Keys.Any() ?
                Math.Min(Columns.Count, ColumnsFillWeights.Keys.Max() + 1)  // whichever is smaller
                : 0;

            for (var col = 0; col < _limit; col++)
            {
                total += (_hiddenColumns.Contains(col) | // if that column is hidden...
                    !ColumnsFillWeights.Keys.Contains(col)) ? // ...or has no weight attributed to itself
                    0 : // then zero
                    ColumnsFillWeights[col]; // otherwise - get the weight
            }

            if (total == 0)
            {
                return; // we shall not divide by 0
            }
            #endregion

            #region adjusting column widths
            SuspendLayout();
            for (var col = 0; col < Columns.Count; col++)
            {
                if (_hiddenColumns.Contains(col))                    
                {
                    Columns[col].Width = 0; // hiding
                    continue;
                }
                // else...
                if (ColumnsFillWeights.Keys.Contains(col))
                {
                    Columns[col].Width = ColumnsFillWeights[col] *
                        (Width - SystemInformation.VerticalScrollBarWidth -
                        SystemInformation.Border3DSize.Width * 2) /
                        total;
                    /* we should be checking whether or not the scrollbar is actually visible at the moment...
                     * assuming it always is == cutting corners a bit...
                     * might need to get back to it */
                }
            }
            ResumeLayout();
            #endregion
        }
    }
}
